home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MISC.SWG / 0032_Modify EXE constants.pas < prev    next >
Pascal/Delphi Source File  |  1993-08-27  |  8KB  |  221 lines

  1. (*
  2. GABE KRUPA
  3.  
  4. > I need to add some information to the end of an EXE file and be able
  5. > Say a PCX image for example.  I'm concerned about the EXE file alread
  6. > open due to being executed.  Does info tacked to the end of an EXE ge
  7. > into memory automatically, etc.  I haven't tried this yet but am abou
  8. > hoping someone who has tried it can assist me to avoid some of the pi
  9. > they may have encountered.  Thanks.  (BTW, I am experienced in Pas &
  10.  
  11.   Well, I made a unit for that purpose, but my unit only tacks on 1K of
  12. storage space... You can make it as large as you want it, but it'll be a
  13. REAL time consumer and it might push your text editor to the limits (I'm
  14. not sure if the IDE has a file size limit).
  15.  
  16.   Here it is (in a VERY shortened version )
  17. }
  18. unit inject1k;
  19.  
  20. interface
  21. implementation
  22. const doesnt_matter_what_this_is_called : boolean = false;
  23.  
  24. procedure never_really_call_this_procedure;
  25. begin
  26.   if doesnt_matter_what_this_is_called then
  27.     inline( 228/229/230/231/231/233/234/  { this I use for a ID string }
  28.             234/234/234/234/234/234/234/
  29.             234/234/234/234/243/234/234/
  30. { repeat as many times until you get enough .. each '234/' is 1 byte }
  31.             234/234/234/234/234/234/234/
  32.             234/234/234/234/234/234/234/  { this is the actual 'junk' }
  33.            ); { inline }
  34. end; { procedure }
  35.  
  36. end. { unit }
  37. {
  38.   I only inject 1024 into my EXE file... If you want, you can make
  39. identical units like that, but the DATA area will NOT be in one long
  40. string unless all the bytes are in one unit.
  41.   I use the ID string to correctly place the file pointer. Just open the
  42. EXE, read in bytes until you get a 228. Read another, if it's a 229
  43. etc.. Keep looping until you get a 228-229-230-231-232-233-234 and then
  44. you can start reading/writing. It's by no means the easiest way, but I
  45. prefer it over trying to append to the end. I tried that, but I kept
  46. getting errors and such. As long as the PCX file is fairly small, you
  47. won't have too much of a problem.
  48.   I'm not sure what the chances are, they must be pretty slim to find a
  49. string (228-234) one after the other in an EXE. If you think they are
  50. higher, or whatever, just put your own in. You could probably even put
  51. text in like this:
  52. }
  53. inline('D'/'A'/'T'/'A'/' '/'S'/'T'/'A'/'R'/'T'/'S'/' '/'H'/'E'/'R'/'E'/
  54. 111/111/111/111  { etc... } );
  55. {
  56.          I hope this helps, or gives you some ideas. Note, the unit will
  57. be about TWICE as large as the number of bytes you inject (maybe 1000
  58. more), but the EXE will only increse by the number you add. I'm pretty
  59. sure that the extra bytes are just data/debug info in the TPU file.
  60. *)
  61.  
  62. {
  63. MARK LEWIS
  64.  
  65. > I need to add some information to the end of an EXE file and be able
  66. > Say a PCX image for example.  I'm concerned about the EXE file alread
  67.  
  68. [... trim ...]
  69.  
  70. > Well, I made a unit for that purpose, but my unit only tacks on
  71. > 1K of storage space... You can make it as large as you want it,
  72. > but it'll be a REAL time consumer and it might push your text
  73. > editor to the limits (I'm not sure if the IDE has a file size
  74. > limit). Here it is (in a VERY shortened version )
  75. > unit inject1k;
  76.  
  77. [... trim ...]
  78.  
  79. interesting<<smile>>... i never thought of doing it like that.. hehe.. here's
  80. a unit i got from this echo or the other PASCAL echo several years ago.. i've
  81. used it in self-limiting programs (ones that only run a certain number of
  82. times) and other programs that may be subject to hacking of various forms...
  83. i've modified it slightly for my purposes...
  84. }
  85. unit selfmod;
  86.  
  87. { Allows a program to self modify a typed constant in the .exe file.  It     }
  88. { also performs an automatic checksum type .exe file integrity check.        }
  89. { A longint value is added to the end of the exe file.  This can be read by  }
  90. { a separate configuration program to enable it to determine the start of    }
  91. { the programs configuration data area.  To use this the configuration       }
  92. { typed constant should be added immediately following the declaration of    }
  93. { ExeData.                                                                   }
  94. { Where this unit is used, it should always be the FIRST unit listed in the  }
  95. { uses declaration area of the main program.                                 }
  96. { Requires DOS 3.3 or later.  Program must not be used with PKLite or LZExe  }
  97. { or any similar exe file compression programs.                              }
  98. { The stack size needed is at least 9,000 bytes.                             }
  99.  
  100. interface
  101.  
  102. type
  103.   ExeDatatype    = record
  104.                      IDStr      : string[8];
  105.                      FirstTime  : boolean;
  106.                      Hsize      : word;
  107.                      ExeSize    : longint;
  108.                      CheckSum   : longint;
  109.                      StartConst : longint;
  110.                    end;
  111.  
  112. const
  113.   ExeData : ExeDatatype = (IDStr     : 'IDSTRING';
  114.                            FirstTime : true;
  115.                            Hsize     : 0;
  116.                            ExeSize   : 0;
  117.                            CheckSum  : 0;
  118.                            StartConst: 0);
  119.  
  120. { IMPORTANT: Put any config data typed constants here }
  121.  
  122. procedure Write2Exec(var data; size: word);
  123.  
  124. {============================================================================}
  125.  
  126. implementation
  127.  
  128. procedure InitConstants;
  129.   var
  130.     f           : file;
  131.     tbuff       : array[0..1] of word;
  132.  
  133.   function GetCheckSum : longint;
  134.     { Performs a checksum calculation on the exe file }
  135.     var
  136.       finished  : boolean;
  137.       x,
  138.       CSum      : longint;
  139.       BytesRead : word;
  140.       buffer    : array[0..4095] of word;
  141.     begin
  142.       {$I-}
  143.       seek(f,0);
  144.       finished := false;  CSum := 0;  x := 0;
  145.       BlockRead(f,buffer,sizeof(buffer),BytesRead);
  146.       while not finished do begin             { do the checksum calculations }
  147.         repeat         { until file has been read up to start of config area }
  148.           inc(CSum,buffer[x mod 4096]);
  149.           inc(x);
  150.           finished := ((x shl 1) >= ExeData.StartConst);
  151.         until ((x mod 4096) = 0) or finished;
  152.         if not finished then                { data area has not been reached }
  153.           BlockRead(f,buffer,sizeof(buffer),BytesRead);
  154.       end;
  155.       GetCheckSum := CSum;
  156.     end;
  157.  
  158.   begin
  159.     assign(f, ParamStr(0));
  160.     {$I-} Reset(f,1);
  161.     with ExeData do begin
  162.       if FirstTime and (IOResult = 0) then begin
  163.         Seek(f,2);                  { this location has the executable size }
  164.         BlockRead(f,tbuff,4);
  165.         ExeSize := tbuff[0]+(pred(tbuff[1]) shl 9);
  166.         seek(f,8);                                   {  get the header size }
  167.         BlockRead(f,hsize,2);
  168.         FirstTime := false;
  169.         StartConst := longint(hsize+Seg(ExeData)-PrefixSeg) shl 4 +
  170.                       Ofs(ExeData) - 256;
  171.         CheckSum := GetCheckSum;
  172.         Seek(f,StartConst);
  173.         BlockWrite(f,ExeData,sizeof(ExeData));
  174.         seek(f,FileSize(f));
  175.         BlockWrite(f,StartConst,4);
  176.       end
  177.       else
  178.         if GetCheckSum <> CheckSum then begin
  179.           writeln;
  180.           writeln(#7,#7,'Program file has been UNLAWFULLY modified!',#7,#7);
  181.           writeln;
  182.           writeln('It may have a Virus attached or someone may have made');
  183.           writeln('an attempt to HACK it. You should check your system for');
  184.           writeln('virus'' before continuing....');
  185.           writeln;
  186.           writeln('Please reinstall the .EXE file from the original archive.');
  187.           writeln('Aborting....');
  188.           halt(255);
  189.         end
  190.         else
  191.           begin
  192.             writeln;
  193.             writeln('Integrity Validated.');
  194.           end;
  195.     end;  { with }
  196.     Close(f); {$I+}
  197.     if IOResult <> 0 then begin
  198.       writeln('Unable to initialise program');
  199.       halt;
  200.     end;
  201.   end; { InitConstants }
  202.  
  203. procedure Write2Exec(var data; size: word);
  204.  { writes a new typed constant into the executable file. }
  205.   var
  206.      f          : file;
  207.   begin
  208.     assign(f, ParamStr(0));
  209.     {$I-} Reset(f,1);
  210.     Seek(f,longint(ExeData.Hsize+Seg(data)-PrefixSeg) shl 4 + Ofs(data)- 256);
  211.     BlockWrite(f,data,size);
  212.     Close(f); {$I+}
  213.     if IOResult <> 0 then;
  214.   end; { Write2Exec }
  215.  
  216. begin
  217.   writeln('Please Standby...');
  218.   InitConstants;
  219. end.
  220.  
  221.